/*
* 树形相关操作
* */

const tree = {}

tree.replaceFields = {
    // 唯一标识属性名
    id: 'id',
    // 父节点标识属性名
    pid: 'parentId',
    // 子节点属性名
    children: 'children'
}

/**
 * @description 设置字段
 * @param {Object} config
 */
tree.setConfig = function (config) {
    tree.replaceFields =  Object.assign({}, this.replaceFields, config)
}


/**
 * @description 树形转列表
 * @param {Array} tree
 * @param {Array} result
 */
tree.treeToList = function (tree, result = []) {
    tree.forEach(node => {
        result.push(node)
        node[this.replaceFields.children] && this.treeToList(node[this.replaceFields.children], result)
    })
    return result
}

/**
 * @description 列表转树形
 * @param {Array} list
 */
tree.listToTree = function (list) {
    let info = list.reduce((map, node) => (map[node[this.replaceFields.id]] = node, node.children = [], map), {})
    return list.filter(node => {
        info[node[this.replaceFields.parentId]] && info[node[this.replaceFields.parentId]].children.push(node)
        return !node[this.replaceFields.parentId]
    })
}

/**
 * @description 树查找节点
 * @param {Array} tree
 * @param {Function} func
 */
tree.treeFind = function (tree, func) {
    const {children} = config, list = [...tree]
    for (let node of list) {
        if (func(node)) return node
        node[children] && list.push(...node[children])
    }
    return null
}

/**
 * @description 树查找节点
 * @param {Array} tree
 * @param {Function} func
 */
tree.treeFind = function (tree, func) {
    for (const data of tree) {
        if (func(data)) return data
        if (data[this.replaceFields.children]) {
            const res = this.treeFind(data[this.replaceFields.children], func)
            if (res) return res
        }
    }
    return null
}

/**
 * @description 树查找节点路径
 * @param {Array} tree
 * @param {Function} func
 * @param {Array} path
 */
tree.treeFindPath = function (tree, func, path = []) {
    if (!tree) return []
    for (const data of tree) {
        path.push(data)
        if (func(data)) return path
        if (data[this.replaceFields.children]) {
            const findChildren = this.treeFindPath(data[this.replaceFields.children], func, path)
            if (findChildren.length) return findChildren
        }
        path.pop()
    }
    return []
}

/**
 * @description 树查找节点路径(多节点)
 * @param {Array} tree
 * @param {Function} func
 * @param {Array} path
 */
tree.treeFindPathS = function (tree, func, path = []) {
    if (!tree) return []
    for (const data of tree) {
        path.push(data)
        func(data) && result.push([...path])
        data[this.replaceFields.children] && this.treeFindPathS(data[this.replaceFields.children], func, path)
        path.pop()
    }
    return []
}


export default tree
